home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 25
/
AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso
/
PublicDomain
/
Anwendungen
/
DetotterButton
/
DetotterMouseButton.mod
< prev
next >
Wrap
Text File
|
2000-03-23
|
14KB
|
363 lines
|##########|
|#MAGIC #|GNOLIEBE
|#PROJECT #|"DetotterMouseButton"
|#PATHS #|"StdProject"
|#LINK #|"c:"
|#GUIDE #|""
|#STACK #|"4096"
|#FLAGS #|xx-x-x--xxx-xxx-x---------------
|#USERSW #|-x------------------------------
|#USERMASK#|-x------------------------------
|#SWITCHES#|xx---xxxxx-xx---
|##########|
MODULE DetotterMouseButton;
(**************************************************************************
*
* DetotterMouseButton.mod
* based on Swap_Buttons.c from the Amiga developer CD V1.1
*
* This detotters a button of an old mouse.
* The Cluster code installs and removes the input.device handler and
* manages the timer messages.
*
* The handler is written in assembly code since it is important that
* handlers be as fast as possible while processing the input events.
*
*)
$$IF Final THEN
$$RangeChk := FALSE
$$OverflowChk := FALSE
$$ReturnChk := FALSE
$$StrZeroChk := FALSE
$$StackChk := FALSE
$$NilChk := FALSE
$$Debug := FALSE
$$EntryCode := FALSE
$$END
FROM Input IMPORT All;
FROM System IMPORT Regs;
FROM Exec IMPORT MsgGrp, InterruptPtr, SignalGrp, LibraryPtr;
TYPE
DetotterDataPtr = POINTER TO DetotterData;
DetotterData =
RECORD
execBase : LibraryPtr; | Fast access to the ExecBase
delayedEvent : InputEvent; | Storage for the delayed release event
delayed : BOOLEAN; | Is delayedEvent valid?
qualifier : Qualifiers; | Qualifier bit for the processed mouse button
pressed : QualifierSet; | The qualifier bit is set if the virtual button is pressed
rawCode : CARDINAL; | Raw key code for the processed button
task : TaskPtr; | Main task
abortDelaySigSet,
delaySigSet : TaskSigSet; | Signals the main task listens to
END;
$$RangeChk := FALSE
$$OverflowChk := FALSE
$$ReturnChk := FALSE
$$StrZeroChk := FALSE
$$StackChk := FALSE
$$NilChk := FALSE
$$Debug := FALSE
$$EntryCode := FALSE
PROCEDURE Detotter (event IN A0 : InputEventPtr;
data IN A1 : DetotterDataPtr) : InputEventPtr;
VAR
code IN D2 : CARDINAL;
qualifier IN D3 : QualifierSet;
|
| The event list gets passed to you in a0.
| The InputHandler.data field is passed to you in a1.
|
| On exit you must return the event list in d0. In this way
| you could add or remove items from the event list.
|
CONST
Signal = -324;
buttonMask = CAST(QualifierSet,INTEGER(-1)) - QualifierSet:{leftButton, midButton, rightButton};
| Compiler doesn't like this
|detotterDataPtr = DetotterDataPtr(NIL);
|delayedEventOffset = detotterDataPtr.delayedEvent'PTR;
|delayedEventOffset = DetotterDataPtr(NIL).delayedEvent'ADR;
BEGIN
ASSEMBLE (
_Detotter:
move event,-(a7) | Save the event list
move.l d2-d3/a2,-(a7) | Save other registers
|
| Since the event list could be a linked list, we start a loop
| here to handle all of the events passed to us.
|
CheckLoop:
|
| The actual button up/down events are transmitted as the
| code field in RAWMOUSE events. The code field must the be
| checked and modified when needed on RAWMOUSE events. If the
| event is not a RAWMOUSE, we are done with it.
|
move event.qualifier,qualifier | Get qualifier set ...
move event.code,code | Get code ...
cmp #Class.rawmouse,event.class | Check for mouse
bne FixQualifiers | If not, next...
move code,d0 | Duplicate ...
bclr #7,d0 | Mask UP_PREFIX
cmp data.rawCode,d0 | Check for button
bne FixQualifiers | No button to care about
|(* begin of debug block, if block is commented out, the thing should not crash
| The button to detotter has changed
btst #7,code | Is it pressed ?
beq ButtonPressed
ButtonReleased: | Button is physically released
lea data.delayedEvent,a2
cmp a2,event | Is this the message we delayed?
beq PassDeferedRelease | If yes, pass it without delaying again
tst data.delayed | Is there a event delayed, already?
bne RedeferRelease | Yes seems so
DeferRelease: | A new release event occured
| InputEvent'SIZE = 22
move event,-(a7)
|lea data.delayedEvent,a2 | We have done this some lines before already
move.l (event)+,(a2)+ | Store this event
move.l (event)+,(a2)+
move.l (event)+,(a2)+
move.l (event)+,(a2)+
move.l (event)+,(a2)+
move.w (event)+,(a2)+
move (a7)+,event
move #-1,data.delayed | Mark this copy as valid
RedeferRelease:
| There is already a deferred release event, flush the current only
SignalMainTask: | Tell the main task, that it has to start a timer
move.l a0/a1/a6,-(a7)
move.l data.execBase,a6
move.l data.delaySigSet,d0
move.l data.task,a1 | Since data = a1 we have to write this last
jsr Signal(a6) | Signal (main task, delay signal);
move.l (a7)+,a0/a1/a6
bra FlushMessage | Trash this message, since it is either stored or double
PassDeferedRelease: | We shall pass this message without parsing
clr data.delayed | This stops the delay state
clr data.pressed | Let's clear the corresponding qualifier bit in our internal qualifier set
bra NextEvent | This hasn't to be processed anymore, qualifiers are already correct
ButtonPressed:
tst data.delayed | Do we hold a delayed release event?
bne AbortDelay | Yes, so we will flush this and the delayed event
move data.qualifier,d0 | No, so we pass the button press event
clr.w d1 | and refresh the internal qualifier set
bset d0,d1 | according to this change
move d1,data.pressed
bra FixQualifiers
AbortDelay:
clr data.delayed | This stops the delay state, too
move.l a0/a1/a6,-(a7)
move.l data.execBase,a6
move.l data.abortDelaySigSet,d0
move.l data.task,a1 | Since data = a1 we have to write this last
jsr Signal(a6) | Signal (main task, delay abort signal);
move.l (a7)+,a0/a1/a6
FlushMessage:
move #Input.noButton,code | Setting code to noButton turns this message into a dummy event
bra StoreEvent | This hasn't to be processed anymore, qualifiers are already correct
| end of block *)
|
| Since we are changing mouse button events, we need to make
| sure that we change the qualifiers on all of the messages. The
| mouse buttons are tracked in the message qualifiers
| for use in such things as dragging. To make sure that we continue
| to drag correctly, we change the qualifiers.
|
FixQualifiers:
move data.qualifier,d0
bclr d0,qualifier
or data.pressed,qualifier | Set the processed qualifier to the emulated state
StoreEvent:
move code,event.code | Save back...
move qualifier,event.qualifier
|move.l #$123134,0 | provoke Enforcer
|
| The event list is linked via a pointer to the next event
| in the first element of the structure. That is why it is not
| nessesary to use: move.l ie_NextEvent(a0),d0
|
| The reason I move to d0 first is that this also checks for zero.
| The last event in the list will have a NULL ie_NextEvent field.
| This is NOT as standard EXEC list where the